﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;
using ProjetoSolo.QueroGas.Aplicacao.ServicosExternos;
using ProjetoSolo.QueroGas.Dominio.Entidades;
using ProjetoSolo.QueroGas.Infraestrutura.Validacao;

namespace ProjetoSolo.QueroGas.Infraestrutura.ServicosWeb
{
    public class ServicoNotificacaoEmail : IServicoNotificacao
    {
        public void EnviarNotificacao(string remetente, IEnumerable<string> destinatarios, string assunto, string mensagem)
        {
            try
            {
                SmtpClient smtp = this.RecuperarDadosServidorSmtp();
                MailMessage mensagemEmail = this.MontarEmail(remetente, destinatarios, assunto, mensagem);

                smtp.Send(mensagemEmail);
            }
            catch (Exception ex)
            {
                throw new Exception("Erro ao enviar email para o destinatario.\n" + ex.Message);
            }
        }

        private MailMessage MontarEmail(string remetente, IEnumerable<string> destinatarios, string assunto, string mensagem)
        {
            MailMessage email = new MailMessage
            {
                From = new MailAddress(remetente),
                Subject = assunto,
                Body = mensagem,
                IsBodyHtml = true
            };

            foreach (var destinatario in destinatarios)
            {
                email.To.Add(destinatario);
            }

            return email;
        }

        private SmtpClient RecuperarDadosServidorSmtp()
        {
            SmtpClient smtp = new SmtpClient
            {
                Host = RecuperarHostSmtp(),
                Port = RecuperarPortaSmtp(),
                Credentials = RecuperarCredenciaisSmtp(),
                EnableSsl = RecuperarConfiguracaoSsl()
            };

            return smtp;
        }

        private string RecuperarHostSmtp()
        {
            string servidorSmtp = ConfigurationManager.AppSettings["smtp"];

            RegraValidacao.VerificarStringVazia(servidorSmtp, "A chave 'smtp' não está definida no web.config ou está com a propriedade 'value' vazia");

            return servidorSmtp;
        }

        private int RecuperarPortaSmtp()
        {
            int portaSmtp = 0;
            string portaSmtpConfig = ConfigurationManager.AppSettings["portaSmtp"];

            RegraValidacao.VerificarStringVazia(portaSmtpConfig, "A chave 'portaSmtp' não está definida no web.config ou está com a propriedade 'value' vazia");

            try
            {
                portaSmtp = Int32.Parse(portaSmtpConfig);
            }
            catch (Exception)
            {
                throw new Exception("Erro ao converter o valor da chave 'portaSmtp' informada. O valor deve ser um número inteiro.");
            }

            return portaSmtp;
        }

        private NetworkCredential RecuperarCredenciaisSmtp()
        {
            string usuarioSmtp = ConfigurationManager.AppSettings["usuarioSmtp"];
            string senhaSmtp = ConfigurationManager.AppSettings["senhaSmtp"];

            RegraValidacao.VerificarStringVazia(usuarioSmtp, "A chave 'usuarioSmtp' não está definida no web.config ou está com a propriedade 'value' vazia");
            RegraValidacao.VerificarStringVazia(senhaSmtp, "A chave 'senhaSmtp' não está definida no web.config ou está com a propriedade 'value' vazia");

            return new NetworkCredential(usuarioSmtp, senhaSmtp);
        }

        private bool RecuperarConfiguracaoSsl()
        {
            bool sslHabilitado = false;
            string sslConfig = ConfigurationManager.AppSettings["sslSmtp"];

            RegraValidacao.VerificarStringVazia(sslConfig, "A chave 'sslSmtp' não está definida no web.config ou está com a propriedade 'value' vazia");
            
            if (sslConfig != "0" && sslConfig != "1")
                throw new Exception("O valor informado para a chave 'sslSmtp' é inválido. Os valores válidos são 0 para desbilitar o ssl ou 1 para habilitar o ssl.");

            if (sslConfig == "1")
                sslHabilitado = true;

            return sslHabilitado;
        }
    }
}
